在原先的 Board 元件中,加入一個按鈕,在被點擊時,改成顯示一個文字輸入框,讓使用者輸入新卡片的內容:
import React from "react";
import styles from "./Board.module.scss";
const Board = props => {
  const [isEditingName, setIsEditingName] = React.useState(false);
  
  // 加入此 state 來控制是否正在新增卡片
  const [isAddingCard, setIsAddingCard] = React.useState(false);
  return (
    <div className={styles.board}>
      <button
        className={styles.closeButton}
        onClick={() => {
          props.dispatch({
            type: "REMOVE_BOARD",
            payload: {
              boardId: props.id
            }
          });
        }}
      >
        x
      </button>
      {isEditingName ? (
        <input
          autoFocus
          value={props.name}
          className={styles.editNameInput}
          onChange={e => {
            dispatch({
              type: "CHANGE_BOARD_NAME",
              payload: {
                boardId: props.id,
                boardName: e.target.value
              }
            });
          }}
          onKeyPress={e => {
            if (e.key === "Enter") {
              setIsEditingName(false);
            }
          }}
        />
      ) : (
        <h2
          className={styles.name}
          onClick={() => setIsEditingName(true)}
        >
          {props.name}
        </h2>
      )}
      {/* 新增以下程式碼 */}
      {isAddingCard ? (
        <input autoFocus />
      ) : (
        <button
          // 偵測按鈕被點擊的事件
          onClick={() => setIsAddingCard(true)}
        >
          +新增卡片
        </button>
      )}
    </div>
  );
};
接著新增一個 state 來控制文字輸入框中的內容:
import React from "react";
import styles from "./Board.module.scss";
const Board = props => {
  const [isEditingName, setIsEditingName] = React.useState(false);
  const [isAddingCard, setIsAddingCard] = React.useState(false);
  
  // 加入此 state 來控制文字輸入框中的內容
  const [inputValue, setInputValue] = React.useState("");
  return (
    <div className={styles.board}>
      <button
        className={styles.closeButton}
        onClick={() => {
          props.dispatch({
            type: "REMOVE_BOARD",
            payload: {
              boardId: props.id
            }
          });
        }}
      >
        x
      </button>
      {isEditingName ? (
        <input
          autoFocus
          value={props.name}
          className={styles.editNameInput}
          onChange={e => {
            dispatch({
              type: "CHANGE_BOARD_NAME",
              payload: {
                boardId: props.id,
                boardName: e.target.value
              }
            });
          }}
          onKeyPress={e => {
            if (e.key === "Enter") {
              setIsEditingName(false);
            }
          }}
        />
      ) : (
        <h2
          className={styles.name}
          onClick={() => setIsEditingName(true)}
        >
          {props.name}
        </h2>
      )}
      {isAddingCard ? (
        <input
          autoFocus
          // 傳入 inputValue 的 state
          value={inputValue}
          // 偵測使用者輸入文字的事件
          onChange={e => setInputValue(e.target.value)}
        />
      ) : (
        <button
          onClick={() => setIsAddingCard(true)}
        >
          +新增卡片
        </button>
      )}
    </div>
  );
};
再來希望使用者按下 Enter 時新增卡片:
import React from "react";
import styles from "./Board.module.scss";
const Board = props => {
  const [isEditingName, setIsEditingName] = React.useState(false);
  const [isAddingCard, setIsAddingCard] = React.useState(false);
  const [inputValue, setInputValue] = React.useState("");
  return (
    <div className={styles.board}>
      <button
        className={styles.closeButton}
        onClick={() => {
          props.dispatch({
            type: "REMOVE_BOARD",
            payload: {
              boardId: props.id
            }
          });
        }}
      >
        x
      </button>
      {isEditingName ? (
        <input
          autoFocus
          value={props.name}
          className={styles.editNameInput}
          onChange={e => {
            dispatch({
              type: "CHANGE_BOARD_NAME",
              payload: {
                boardId: props.id,
                boardName: e.target.value
              }
            });
          }}
          onKeyPress={e => {
            if (e.key === "Enter") {
              setIsEditingName(false);
            }
          }}
        />
      ) : (
        <h2
          className={styles.name}
          onClick={() => setIsEditingName(true)}
        >
          {props.name}
        </h2>
      )}
      {isAddingCard ? (
        <input
          autoFocus
          value={inputValue}
          onChange={e => setInputValue(e.target.value)}
          // 偵測按下 Enter 的事件
          onKeyPress={e => {
            if (e.key === "Enter") {
              dispatch({
                type: "ADD_CARD",
                payload: {
                  boardId: props.id,
                  cardValue: inputValue.trim()
                }
              });
              // 同時清除文字框中的內容
              setInputValue("");
              // 同時離開新增卡片模式
              setIsAddingCard(false);
            }
          }}
        />
      ) : (
        <button
          onClick={() => setIsAddingCard(true)}
        >
          +新增卡片
        </button>
      )}
    </div>
  );
};
最後在 Board.module.scss 加入樣式:
.board {
  .addCardInput {
    padding: 8px;
    margin: 4px 0;
  }
  .addCardButton {
    color: white;
    padding: 8px;
    margin: 4px 0;
    &:hover {
      text-decoration: underline;
    }
  }
}
Board 元件中加入 className(以下僅表示大致元素結構):
<div className={styles.board}>
  <button className={styles.closeButton}>
    x
  </button>
  {isEditingName ? (
    <input className={styles.editNameInput} />
  ) : (
    <h2 className={styles.name}>
      {props.name}
    </h2>
  )}
  {isAddingCard ? (
    <input className={styles.addCardInput} />
  ) : (
    <button className={styles.addCardButton}>
      +新增卡片
    </button>
  )}
</div>

到目前為止,我們可以輸入新卡片內容,不過按下新增按鈕還看不到新增出來的卡片,是因為新卡片的資料雖然被新增到 useReducer 的 state 中,但我們並沒有將 state 中的資料顯示出來。
建立卡片的元件來顯示卡片的資料並且加入編輯卡片內容的功能。